#import "BluetoothService.h"

#import "btstack/btstack.h"
#import "btstack/hci_cmds.h"
#import "btstack/run_loop.h"
#import "btstack/utils.h"

static BluetoothService * m_BluetoothService = nil;

bd_addr_t _addr = { 0x00, 0x80, 0x25, 0x16, 0x4E, 0x91 }; // MAC-Adresse des Wechselrichters
int _rfcomm_channel = 1;
uint16_t rfcomm_channel_id;

@interface BluetoothService (privat)
- (void)handlePacket:(uint8_t) packet_type forChannel:(uint16_t) channel andData:(uint8_t *)packet withLen:(uint16_t) size;
@end

static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
	[m_BluetoothService handlePacket:packet_type forChannel:channel andData:packet withLen:size];
}

@implementation BluetoothService

@synthesize listeners;
@synthesize messageValue;

-(BluetoothService *) init {
	self = [super init];
	if (!self) 
	{
		return self;
	}
	state = kDeactivated;
	[self setListeners:[[NSMutableSet alloc] init]];
	
	run_loop_init(RUN_LOOP_COCOA);
	bt_register_packet_handler(packet_handler);
	return self;
}

+(BluetoothService *) sharedInstance {
	if (!m_BluetoothService) 
	{
		m_BluetoothService = [[BluetoothService alloc] init];
	}
	
	return m_BluetoothService;
}

-(void) activate {
	bt_open();
	//TODO fehler abfangen
	bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON);
}

-(void) addListener:(id<BluetoothServiceListener>)listener {
	[listeners addObject:listener];
}

-(void) removeListener:(id<BluetoothServiceListener>)listener {
	[listeners removeObject:listener];
}

-(void) handlePacket:(uint8_t)packet_type forChannel:(uint16_t)channel andData:(uint8_t *)packet withLen:(uint16_t) size {
	bd_addr_t event_addr;
	uint16_t mtu;
		
	switch (packet_type) {
		case RFCOMM_DATA_PACKET:
			[self handlePacket_Data:packet:size];
			break;
			
		case HCI_EVENT_PACKET:
			switch (packet[0]) {
					
				case BTSTACK_EVENT_POWERON_FAILED:
					// handle HCI init failure
					printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n");
					exit(1);
					break;		
					
				case BTSTACK_EVENT_STATE:
					// bt stack activated, get started
                    if (packet[2] == HCI_STATE_WORKING) 
					{
						bt_send_cmd(&rfcomm_create_channel, _addr, _rfcomm_channel);
						[self sendActivatedEvent];
					}
					break;
					
				case HCI_EVENT_PIN_CODE_REQUEST:
					// inform about pin code request
					printf("Using PIN 0000\n");
					bt_flip_addr(event_addr, &packet[2]); 
					bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
					break;
					
				case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
					// data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
					if (packet[2]) {
						printf("RFCOMM channel open failed, status %u\n", packet[2]);
					} else {
						rfcomm_channel_id = READ_BT_16(packet, 12);
						mtu = READ_BT_16(packet, 14);
						printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu);
						[self sendRfcommChannelOpenedEvent];
					}
					break;

				case RFCOMM_EVENT_PERSISTENT_CHANNEL:
					break;
					
				case HCI_EVENT_DISCONNECTION_COMPLETE:
					// connection closed -> quit test app
					printf("Basebank connection closed\n");
					[self sendDeactivatedEvent];
					break;
					
				default:
					break;
			}
			break;
		default:
			break;
	}
}

u16 fcstab[256] = {
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};

-(unsigned char) conv:(char *)nn {
    unsigned char tt = 0, res = 0;
    
    for (int i=0; i < 2; i++) {
        switch (nn[i]) {
                
            case 65: /*A*/
            case 97: /*a*/
                tt = 10;
                break;
                
            case 66: /*B*/
            case 98: /*b*/
                tt = 11;
                break;
                
            case 67: /*C*/
            case 99: /*c*/
                tt = 12;
                break;
                
            case 68: /*D*/
            case 100: /*d*/
                tt = 13;
                break;
                
            case 69: /*E*/
            case 101: /*e*/
                tt = 14;
                break;
                
            case 70: /*F*/
            case 102: /*f*/
                tt = 15;
                break;
                
            default:
                tt = nn[i] - 48;
        }
        res = res + (tt * pow(16,1-i));
    }
    return res;
}

/*
 * Add escapes (7D) as they are required
 */
-(void) add_escapes:(unsigned char *)cp:(int *)len {
    for (int i=19; i < (*len); i++) {
        switch (cp[i]) {
            case 0x7d :
            case 0x7e :
            case 0x11 :
            case 0x12 :
            case 0x13 :
                for (int j=(*len); j > i; j--) cp[j] = cp[j-1];
                cp[i+1] = cp[i] ^ 0x20;
                cp[i] = 0x7d;
                (*len)++;
        }
    }
}

/*
 * Recalculate and update length to correct for escapes
 */
-(void) fix_length_send:(unsigned char *)cp:(int *)len {
    int delta = 0;
    
    if (cp[1] != (*len) + 1) {
        delta = (*len) + 1 - cp[1];
        cp[3] = (cp[1] + cp[3]) - ((*len) + 1);
        cp[1] = (*len) + 1;
        
        switch (cp[1]) {
            case 0x3a: cp[3]=0x44; break;
            case 0x3b: cp[3]=0x43; break;
            case 0x3c: cp[3]=0x42; break;
            case 0x3d: cp[3]=0x41; break;
            case 0x3e: cp[3]=0x40; break;
            case 0x3f: cp[3]=0x41; break;
            case 0x40: cp[3]=0x3e; break;
            case 0x41: cp[3]=0x3f; break;
            case 0x42: cp[3]=0x3c; break;
            case 0x52: cp[3]=0x2c; break;
            case 0x53: cp[3]=0x2b; break;
            case 0x54: cp[3]=0x2a; break;
            case 0x55: cp[3]=0x29; break;
            case 0x56: cp[3]=0x28; break;
            case 0x57: cp[3]=0x27; break;
            case 0x58: cp[3]=0x26; break;
            case 0x59: cp[3]=0x25; break;
            case 0x5a: cp[3]=0x24; break;
            case 0x5b: cp[3]=0x23; break;
            case 0x5c: cp[3]=0x22; break;
            case 0x5d: cp[3]=0x23; break;
            case 0x5e: cp[3]=0x20; break;
            case 0x5f: cp[3]=0x21; break;
            case 0x60: cp[3]=0x1e; break;
            case 0x61: cp[3]=0x1f; break;
            case 0x62: cp[3]=0x1e; break;
            default: printf("NO CONVERSION!"); break;
        }
    }
}

/*
 * Calculate a new fcs given the current fcs and the new data.
 */
-(u16) pppfcs16:(u16)fcs:(void *)_cp:(int)len {
    register unsigned char *cp = (unsigned char *)_cp;
    /* don't worry about the efficiency of these asserts here.  gcc will
     * recognise that the asserted expressions are constant and remove them.
     * Whether they are usefull is another question. 
     */
    assert(sizeof(u16) == 2);
    assert(((u16) - 1) > 0);
    while (len--)
        fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
    return (fcs);
}

/*
 * How to use the fcs
 */
-(void) tryfcs16:(unsigned char *)cp:(int)len:(int)cc:(uint8_t *)send {
    u16 trialfcs;
    unsigned char stripped[1024] = { 0 };
    
    memcpy(stripped, cp, len);
    /* add on output */
    trialfcs = [self pppfcs16:0xffff:stripped:len];
    trialfcs ^= 0xffff;               /* complement */
    send[cc] = (trialfcs & 0x00ff);    /* least significant byte first */
    send[cc+1] = ((trialfcs >> 8) & 0x00ff);
    //cc += 2;
}

/*
 * Recalculate and update length to correct for escapes
 */
-(void) fix_length_received:(unsigned char *)received:(uint16_t *)len {
    //int delta = 0;
    int sum;
    
    if (received[1] != (*len)) {
        sum = received[1] + received[3];
        //delta = (*len) - received[1];
        if ((received[3] != 0x13) && (received[3] != 0x14)) { 
            received[1] = (*len);
            switch (received[1]) {
                case 0x52: received[3] = 0x2C; break;
                case 0x5a: received[3] = 0x24; break;
                case 0x66: received[3] = 0x1A; break;
                case 0x6a: received[3] = 0x14; break;
                default:  received[3] = sum - received[1]; break;
            }
        }
    }
}

int initCounter = 22;
int schritt = 1;
float signalStrength;
NSInteger serialInInteger;

-(void) handlePacket_Data:(uint8_t *)packet:(uint16_t) size {
    if (schritt == 1) {
        uint8_t init[] = { 0x7E, 0x1F, 0x00, 0x61, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x70, 0x00 };
        for (int i=0; i < size; i++) {
            if (packet[i] != init[i]) {
                [self sendMessageReceivedEvent:@"keine Uebereinstimmung"];
            }
            else if ((packet[i] == init[i]) && (initCounter > 0)) {
                if ((i%10 == 0) && (i > 1)) self.messageValue = [NSString stringWithFormat:@"%@ %02X\n", self.messageValue, packet[i]];
                else self.messageValue = [NSString stringWithFormat:@"%@ %02X", self.messageValue, packet[i]];
                initCounter--;
            }
        }
        if (initCounter == 0) {
            uint8_t send[] = { 0x7E, 0x1F, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x02, 0x00, 0x00, 0x04, 0x70, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
            bt_send_rfcomm(rfcomm_channel_id, send, sizeof(send));
            schritt++;
            initCounter = 24;
        }
    }
    
    //[NSThread sleepForTimeInterval:2];
    
    if (schritt == 2) {
        uint8_t init[] = { 0x7E, 0x22, 0x00, 0x5C, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00 };
        for (int i=0; i < size; i++) {
            if (packet[i] != init[i]) {
                [self sendMessageReceivedEvent:@"keine Uebereinstimmung"];
            }
            else if ((packet[i] == init[i]) && (initCounter > 0)) {
                if ((i%10 == 0) && (i > 1)) self.messageValue = [NSString stringWithFormat:@"%@ %02X\n", self.messageValue, packet[i]];
                else self.messageValue = [NSString stringWithFormat:@"%@ %02X", self.messageValue, packet[i]];
                initCounter--;
            }
        }
        if (initCounter > 0) initCounter = 24;
        if (initCounter == 0) {
            uint8_t send[] = { 0x7E, 0x14, 0x00, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x03, 0x00, 0x05, 0x00 };
            bt_send_rfcomm(rfcomm_channel_id, send, sizeof(send));
            schritt++;
            initCounter = 22;
        }
    }
    
    //[NSThread sleepForTimeInterval:2];
    
    if (schritt == 3 || schritt == 4) {
        uint8_t init[] = { 0x7E, 0x18, 0x00, 0x66, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00 };
        for (int i=0; i < size; i++) {
            if (packet[i] != init[i]) {
                [self sendMessageReceivedEvent:@"keine Uebereinstimmung"];
            }
            else if ((packet[i] == init[i]) && (initCounter > 0)) {
                if ((i%10 == 0) && (i > 1)) self.messageValue = [NSString stringWithFormat:@"%@ %02X\n", self.messageValue, packet[i]];
                else self.messageValue = [NSString stringWithFormat:@"%@ %02X", self.messageValue, packet[i]];
                initCounter--;
            }
        }
        if (initCounter > 0) initCounter = 22;
        if (initCounter == 0) {
            if (schritt == 3) {
                signalStrength = (packet[22] * 100.0) / 0xff; // Signalstaerke auslesen
                NSLog([NSString stringWithFormat:@"Bluetooth Signalstaerke = %.0f Prozent", signalStrength]);
            }
            uint8_t send[] = { 0x7E, 0x14, 0x00, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x03, 0x00, 0x05, 0x00 };
            bt_send_rfcomm(rfcomm_channel_id, send, sizeof(send));
            schritt++;
            initCounter = 22;
        }
    }
    
    //[NSThread sleepForTimeInterval:2];
    
    if (schritt == 5) {
        uint8_t init[] = { 0x7E, 0x18, 0x00, 0x66, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00 };
        for (int i=0; i < size; i++) {
            if (packet[i] != init[i]) {
                [self sendMessageReceivedEvent:@"keine Uebereinstimmung"];
            }
            else if ((packet[i] == init[i]) && (initCounter > 0)) {
                if ((i%10 == 0) && (i > 1)) self.messageValue = [NSString stringWithFormat:@"%@ %02X\n", self.messageValue, packet[i]];
                else self.messageValue = [NSString stringWithFormat:@"%@ %02X", self.messageValue, packet[i]];
                initCounter--;
            }
        }
        if (initCounter > 0) initCounter = 22;
        if (initCounter == 0) {
            uint8_t send[] = { 0x7E, 0x3E, 0x00, 0x40, 0xAB, 0x93, 0x44, 0x12, 0x8D, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x7E, 0xFF, 0x03, 0x60, 0x65, 0x09, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x78, 0x00, 0x78, 0x21, 0xBF, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x22, 0x7E };
            bt_send_rfcomm(rfcomm_channel_id, send, sizeof(send));
            uint8_t send2[] = { 0x7E, 0x3A, 0x00, 0x44, 0xAB, 0x93, 0x44, 0x12, 0x8D, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x7E, 0xFF, 0x03, 0x60, 0x65, 0x08, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0x78, 0x00, 0x78, 0x21, 0xBF, 0x3A, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0E, 0x01, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xCC, 0x7E };
            bt_send_rfcomm(rfcomm_channel_id, send2, sizeof(send2));
            uint8_t send3[] = { 0x7E, 0x54, 0x00, 0x2A, 0xAB, 0x93, 0x44, 0x12, 0x8D, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x7E, 0xFF, 0x03, 0x60, 0x65, 0x0E, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x78, 0x00, 0x78, 0x21, 0xBF, 0x3A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x0C, 0x04, 0xFD, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x84, 0x03, 0x00, 0x00, 0x1F, 0xCD, 0x17, 0x50, 0x00, 0x00, 0x00, 0x00, 0xB8, 0xB8, 0xB8, 0xB8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xA2, 0x56, 0x7E };
            // $TIME: get report time and convert
            time_t reporttime = time(NULL);
            char tt[10] = {48,48,48,48,48,48,48,48,48,48};
            char ti[3];
            int timeCounter = 0;
            uint8_t timeInBytes[4];
            sprintf(tt, "%x", (int) reporttime); //convert to a hex in a string
            for (int i=7; i > 0; i = i-2) { //change order and convert to integer
                ti[1] = tt[i];
                ti[0] = tt[i-1];        
                ti[2] = '\0';
                timeInBytes[timeCounter] = [self conv:ti];
                timeCounter++;
            }
            for (int i=62; i > 58; i--) {
                send3[i] = timeInBytes[i-59];
            }
            // $CRC berechnen
            int cc = 79;
            [self tryfcs16:send3 + 19:cc - 19:cc:send3];
            [self add_escapes:send3:&cc];
            [self fix_length_send:send3:&cc];
            send3[1] = 0x52; // manuell abaendern, da verfaelscht wurde
            send3[3] = 0x2C;
            /*NSString * message = nil;
            for (int i=0; i < sizeof(send2); i++) {
                message = [NSString stringWithFormat:@"%@ %02X", message, send2[i]];
            }
            NSLog(message);*/
            // Senden
            bt_send_rfcomm(rfcomm_channel_id, send3, sizeof(send3));
            schritt++;
            initCounter = 10;
        }
    }
    
    //[NSThread sleepForTimeInterval:2];
    
    if (schritt == 6) {
        uint8_t received[] = { 0x7E, 0x6B, 0x00, 0x15, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00 };
        for (int i=0; i < size; i++) {
            if (packet[i] != received[i]) {
                [self sendMessageReceivedEvent:@"keine Uebereinstimmung"];
            }
            if ((packet[i] == received[i]) && (initCounter > 0)) {
                if ((i%10 == 0) && (i > 1)) self.messageValue = [NSString stringWithFormat:@"%@ %02X\n", self.messageValue, packet[i]];
                else self.messageValue = [NSString stringWithFormat:@"%@ %02X", self.messageValue, packet[i]];
                initCounter--;
            }
        }
        if (initCounter > 0) initCounter = 10;
        if (initCounter == 0 && packet[1] == 0x6B && packet[3] == 0x15) {
            [self fix_length_received:packet:&size];
            // Seriennummer auslesen
            uint8_t serial[4];
            serial[3] = packet[40];
            serial[2] = packet[39];
            serial[1] = packet[37] + 1;
            serial[0] = packet[36];
            serialInInteger = *((NSInteger *)serial);
            NSLog([NSString stringWithFormat:@"Seriennummer = %02X:%02X:%02X:%02X => %d", serial[3], serial[2], serial[1], serial[0], serialInInteger]);
            //uint8_t send[] = { 0x7E, 0x14, 0x00, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x03, 0x00, 0x05, 0x00 };
            //bt_send_rfcomm(rfcomm_channel_id, send, sizeof(send));
            schritt++;
            //initCounter = 22;
            bt_send_cmd(&btstack_set_power_mode, HCI_POWER_OFF);
        }
    }
    
    if (packet[1] == 0x54) [self showMessageBox]; 
    
    //[NSThread sleepForTimeInterval:2];
    
    /*if (schritt == 7 || schritt == 8 || schritt == 9) {
        uint8_t received[] = { 0x7E, 0x18, 0x00, 0x66, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00 };
        for (int i=0; i < sizeof(received); i++) {
            if (packet[i] != received[i]) {
                [self sendMessageReceivedEvent:@"keine Uebereinstimmung"];
            }
            else if ((packet[i] == received[i]) && (initCounter > 0)) {
                if ((i%10 == 0) && (i > 1)) self.messageValue = [NSString stringWithFormat:@"%@ %02X\n", self.messageValue, packet[i]];
                else self.messageValue = [NSString stringWithFormat:@"%@ %02X", self.messageValue, packet[i]];
                initCounter--;
            }
        }
        if (initCounter == 0) {
            if (schritt == 7 || schritt == 8) {
                uint8_t send[] = { 0x7E, 0x14, 0x00, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x4E, 0x16, 0x25, 0x80, 0x00, 0x03, 0x00, 0x05, 0x00 };
                bt_send_rfcomm(rfcomm_channel_id, send, sizeof(send));
                initCounter = 22;
            }
            else {
                uint8_t send[] = { 7e 5c 00 22 $ADD2 ff ff ff ff ff ff 01 00 7e ff 03 60 65 10 a0 ff ff ff ff ff ff 00 00 78 00 $UNKNOWN 00 00 00 00 00 00 $CNT 80 0a 02 00 f0 00 6d 23 00 00 6d 23 00 00 6d 23 00 $TIME $TIME $TIME $TIMEZONE 00 00 $TIMESET 01 00 00 00 $CRC 7e };
                bt_send_rfcomm(rfcomm_channel_id, send, sizeof(send));
                //initCounter = 22;
            }
            schritt++;
        }
    }*/
    
    if (packet[1] != 0x54) [NSThread sleepForTimeInterval:2];
    
    if (self.messageValue != @"") {
        NSString * msg = [NSString stringWithFormat:@"%@", self.messageValue];
        [self sendMessageReceivedEvent:msg];
        //NSLog(msg);
        self.messageValue = @"";
    }
    else {
        for (int i=0; i < size; i++) {
            if ((i%10 == 0) && (i > 1)) self.messageValue = [NSString stringWithFormat:@"%@ %02X\n", self.messageValue, packet[i]];
            else self.messageValue = [NSString stringWithFormat:@"%@ %02X", self.messageValue, packet[i]];
        }
        NSString * msg = [NSString stringWithFormat:@"%@", self.messageValue];
        [self sendMessageReceivedEvent:msg];
        //NSLog(msg);
        self.messageValue = @"";
    }
}

-(void) showMessageBox {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Ausgelesene Daten" message:[NSString stringWithFormat:@"Bluetooth Signalst\u00E4rke = %.0f Prozent\nSeriennummer = %d", signalStrength, serialInInteger] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];
    [alert release];
}

-(void) sendActivatedEvent
{
	for (NSObject<BluetoothServiceListener>* listener in listeners) 
	{
		if ([listener respondsToSelector:@selector(activated:)])
		{
			[listener activated:self];
		}
	}
}

-(void) sendDeactivatedEvent
{
	for (NSObject<BluetoothServiceListener>* listener in listeners) 
	{
		if ([listener respondsToSelector:@selector(deactivated:)])
		{
			[listener deactivated:self];
		}
	}
} 

-(void) sendRfcommChannelOpenedEvent
{
	for (NSObject<BluetoothServiceListener>* listener in listeners) 
	{
		if ([listener respondsToSelector:@selector(rfcommChannelOpened)])
		{
			[listener rfcommChannelOpened];
		}
	}
} 

-(void) sendMessageReceivedEvent:(NSString*) message
{
	for (NSObject<BluetoothServiceListener>* listener in listeners) 
	{
		if ([listener respondsToSelector:@selector(messageReceived:)])
		{
			[listener messageReceived:message];
		}
	}
}

@end